package service

import (
	"GoServer/utils/debug"
	"context"
	"errors"
	"github.com/gin-gonic/gin"
	"log"
	"net/http"
	"os"
	"os/signal"
	"sync"
	"syscall"
	"time"
)

type ServerConfig struct {
	Address  string `mapstructure:"address"`
	GameName string `mapstructure:"game_name"`
}

func BeginService(gameName string, port string) {
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()

	var wg sync.WaitGroup

	// 加载配置
	var server = ServerConfig{
		Address:  port,
		GameName: gameName,
	}

	// 系统信号监听
	quit := make(chan os.Signal, 1)
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)

	// 启动所有服务
	go startServer(ctx, server, &wg, RouterRegistry)

	<-quit
	debug.Logln(debug.Info, "接收到关闭信号，准备关闭服务...")
	cancel()
	wg.Wait()
	debug.Logln(debug.Info, "所有服务已优雅退出")
}

func startServer(ctx context.Context, conf ServerConfig, wg *sync.WaitGroup, registry map[string][]RouteBuilder) {
	defer wg.Done()

	builders, ok := registry[conf.Address]
	if !ok || len(builders) == 0 {
		log.Printf("未找到端口 [%s] 的路由构建器，跳过", conf.Address)
		return
	}

	engine := gin.New()

	// 注册所有路由模块
	for _, builder := range builders {
		builder(engine, conf.Address, conf.GameName)
	}

	srv := &http.Server{
		Addr:    conf.Address,
		Handler: engine,
	}

	go func() {
		debug.Logln(debug.Info, "启动服务器监听：", conf.Address)
		if err := srv.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
			log.Printf("服务启动失败 [%s]: %v", conf.Address, err)
		}
	}()

	<-ctx.Done()
	debug.Logln(debug.Info, "正在关闭服务：", conf.Address)

	shutdownCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	if err := srv.Shutdown(shutdownCtx); err != nil {
		log.Printf("服务关闭失败 [%s]: %v", conf.Address, err)
	}
}
